package hook

import (
	"encoding/json"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"cli"
	"gopkg.in/yaml.v2"
	"fmt"
	"bytes"
)

var cfg *config

type config struct{
	Hook *Hook `yaml:"hook"`
}

type Repo struct {
	Name     string   `yaml:"name"`
	Token    string   `yaml:"token"`
	Commands []string `yaml:"commands"`
}

type Hook struct {
	Repos []*Repo  `yaml:"repos"` // [repo.name] repo
}

func Before(ctx *cli.Context) error {
	c := ctx.String("c")
	f,err := os.OpenFile(c,os.O_RDONLY,0777)
	if err != nil {
		return err
	}
	defer f.Close()
	cfg = new(config)
	err = yaml.NewDecoder(f).Decode(cfg)
	if err != nil {
		return err
	}
	return nil
}

func Action(ctx *cli.Context) error {
	http.Handle("/api/deploy",cfg.Hook)
	err := http.ListenAndServe(":8080",nil)
	if err != nil {
		return err
	}
	return nil
}


//
//- http://hook.clearcode.cn/api/deploy
//- github@clearcode.cn
// # notifaction to deploy
//  - curl -i -H "Content-Type:application/json" -H "Authorization:${DEPLOY_TOKEN}"  -X POST -d '{"repo": "clearcode-blog", "branch":"master"}' ${DEPLOY_HOOK}
type HookData struct {
	Repo   string `json:"repo"`
	Branch string `json:"branch"`
	Path   string `json:"path"`
}

func (h Hook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var b = make([]byte, 1024)
	n, _ := r.Body.Read(b)
	r.Body.Close()
	var data = new(HookData)
	err := json.Unmarshal(b[:n], data)
	if err != nil {
		w.WriteHeader(400)
		w.Write([]byte("Bad Request"))
		return
	}
	var repo *Repo
	for _,val := range h.Repos {
		if val.Name == data.Repo {
			repo = val
		}
	}

	if repo == nil {
		w.WriteHeader(400)
		w.Write([]byte("repo not exist"))
		return
	}
	if strings.HasPrefix(repo.Token,"$") {
		repo.Token = os.Getenv(repo.Token[2:len(repo.Token)-1])
	}

	token := r.Header.Get("Authorization")
	if token != repo.Token {
		w.WriteHeader(401)
		w.Write([]byte("UnAuthorization"))
		return
	}
	var bb []byte
	var bufs = bytes.NewBuffer(bb)

	log.Println("get hook:", fmt.Sprintf("%+v",repo))

	cmds := strings.Join(repo.Commands,"\n")
	var cmd *exec.Cmd
	cmd = exec.Command("/bin/bash","-c", cmds)
	cmd.Stderr = bufs
	cmd.Stdout = bufs
	err = cmd.Run()
	if err != nil {
		bufs.WriteString(err.Error())
	}
	log.Println("end hook")
	log.Println(bufs.String())
	bufs.WriteTo(w)
}
